package com.newvpn.fastbest.zenith.net;

import android.annotation.SuppressLint;
import android.util.Log;

import com.newvpn.fastbest.zenith.R;
import com.newvpn.fastbest.zenith.VPNApp;
import com.newvpn.fastbest.zenith.beans.netbeans.AddTimeBean;
import com.newvpn.fastbest.zenith.beans.netbeans.BaseResponse;
import com.newvpn.fastbest.zenith.beans.netbeans.EncryBean;
import com.newvpn.fastbest.zenith.beans.netbeans.PingBean;
import com.newvpn.fastbest.zenith.beans.netbeans.StartBean;
import com.newvpn.fastbest.zenith.beans.netbeans.UserInfo;
import com.newvpn.fastbest.zenith.beans.netbeans.VersionBean;
import com.newvpn.fastbest.zenith.beans.reqbeans.FeedbackBean;
import com.newvpn.fastbest.zenith.beans.reqbeans.NodeBean;
import com.newvpn.fastbest.zenith.beans.reqbeans.ReqAdValue;
import com.newvpn.fastbest.zenith.beans.reqbeans.ReqAddTimeBean;
import com.newvpn.fastbest.zenith.utils.KeyStore;
import com.newvpn.fastbest.zenith.utils.KeyUtils;
import com.newvpn.fastbest.zenith.utils.VLog;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableSource;
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.functions.BiFunction;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Body;
import retrofit2.http.POST;

public enum NetService {
    INSTANCE;

    ApiService service;

    //public String mToken = "";


    public void init(String url) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .client(new OkHttpClient.Builder()
//                        .readTimeout(15, TimeUnit.SECONDS) // 设置读取超时时间
//                        .connectTimeout(15, TimeUnit.SECONDS) // 设置连接超时时间
//                        .writeTimeout(15, TimeUnit.SECONDS) // 设置写入超时时间
                        .addInterceptor(new HeaderInterceptor())
                        .build())
                .build();
        service = retrofit.create(ApiService.class);
    }

    @SuppressLint("CheckResult")
    public Observable<BaseResponse<UserInfo>> getUserInfo() {
        VLog.e("net:" + "getUserInfo()");
        return service.getUserInfo().subscribeOn(Schedulers.io()) // 在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread());
//        ob.subscribe(new Consumer<BaseResponse<UserInfo>>() {
//            @Override
//            public void accept(BaseResponse<UserInfo> userInfoBaseResponse) throws Throwable {
//
//            }
//        }, new Consumer<Throwable>() {
//            @Override
//            public void accept(Throwable throwable) throws Throwable {
//
//            }
//        });
    }

    @SuppressLint("CheckResult")
    public Single<BaseResponse<EncryBean>> getVPNList() {
        VLog.e("net:" + "getVPNList()");
        return service.getVPNList()
                //.timeout(15, TimeUnit.SECONDS,Single.error(new TimeoutException(VPNApp.getBase().getString(R.string.try_again))))
                // 在IO线程进行网络请求
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @SuppressLint("CheckResult")
    public Observable<BaseResponse<EncryBean>> geVPNServerInfo(NodeBean content) {
        VLog.e("net:" + "geVPNServerInfo()");
        return service.geVPNServerInfo(content)
                //.timeout(15, TimeUnit.SECONDS,Single.error(new TimeoutException(VPNApp.getBase().getString(R.string.try_again))))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    ;

    @SuppressLint("CheckResult")
    public Observable<BaseResponse<StartBean>> seesionStart(NodeBean content) {
        VLog.e("net:" + "seesionStart()");
        return service.seesionStart(content).subscribeOn(Schedulers.io()) // 在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread());
    }

    @SuppressLint("CheckResult")
    public Observable<BaseResponse<Void>> seesionEnd(NodeBean content) {
        VLog.e("net:" + "seesionEnd()");
        return service.seesionEnd(content).subscribeOn(Schedulers.io()) // 在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread());
    }

    @SuppressLint("CheckResult")
    public Observable<BaseResponse<PingBean>> seesionPing(NodeBean content) {
        VLog.e("net:" + "seesionPing()");
        return service.seesionPing(content).subscribeOn(Schedulers.io()) // 在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread());
    }

    @SuppressLint("CheckResult")
    public Observable<BaseResponse<Void>> postAdCost(ReqAdValue content) {
        VLog.e("net:" + "postAdCost()");
        return service.postAdCost(content).subscribeOn(Schedulers.io()) // 在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread());
    }

    @SuppressLint("CheckResult")
    public Observable<BaseResponse<EncryBean>> getAdConfig() {
        VLog.e("net:" + "getAdConfig()");
        return service.getAdConfig().subscribeOn(Schedulers.io()) // 在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread());
    }

    @SuppressLint("CheckResult")
    public Observable<BaseResponse<VersionBean>> getVersion() {
        VLog.e("net:" + "getAdConfig()");
        return service.getVersion().subscribeOn(Schedulers.io()) // 在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread());
    }


    @SuppressLint("CheckResult")
    public Observable<BaseResponse<AddTimeBean>> addTime(ReqAddTimeBean content) {
//        VLog.e("net:" + "addTime()");
//        Observable<BaseResponse<AddTimeBean>> timeoutObservable = Observable
//                .timer(1, TimeUnit.SECONDS).subscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
//                .flatMap(aLong -> {
//                            Log.e("addTime", "addTime toutime");
//                            return Observable.error(new TimeoutException("请求超时"));
//                        }
//                );


        Observable<BaseResponse<AddTimeBean>> networkObservable = service.addTime(content)
                .timeout(15, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
        return networkObservable;
    }

    @SuppressLint("CheckResult")
    public Single<BaseResponse<Void>> suggest(FeedbackBean content) {
        VLog.e("net:" + "addTime()");
        return service.suggest(content)
                //.timeout(15, TimeUnit.SECONDS,Single.error(new TimeoutException(VPNApp.getBase().getString(R.string.try_again))))
                .subscribeOn(Schedulers.io())
                // 在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread());
    }


    public void updateToken(String token) {
        //mToken = token;
        KeyStore.INS.putString(KeyUtils.TOKEN, token);
    }
}
